<template>
  <div class="area-picker-container">
    <!-- 触发按钮 -->
    <div class="selected-area" @click="showPicker()">
      <span v-if="selectedProvince">
        {{ selectedProvince }} {{ selectedCity }} {{ selectedDistrict }}
      </span>
      <span v-else class="placeholder">请选择地区</span>
    </div>

    <!-- 选择器弹窗 -->
    <div class="picker-mask" v-if="isPickerVisible" @click="hidePicker"></div>
    <div class="picker-panel" v-if="isPickerVisible">
      <!-- 顶部操作栏 -->
      <div class="picker-header">
        <button class="picker-btn cancel" @click="hidePicker">取消</button>
        <h3 class="picker-title">选择地区</h3>
        <button class="picker-btn confirm" @click="confirmSelection">确认</button>
      </div>

      <!-- 滚动选择区域 -->
      <div class="picker-content">
        <div class="picker-col" ref="provinceCol">
          <ul @touchstart="onTouchStart('province', $event)" @touchmove="onTouchMove('province', $event)"
            @touchend="onTouchEnd('province', $event)">
            <li v-for="(item, index) in provinces" :key="index" :class="{ active: index === provinceIndex }">{{
              item.name }}</li>
          </ul>
        </div>
        <div class="picker-col" ref="cityCol">
          <ul @touchstart="onTouchStart('city', $event)" @touchmove="onTouchMove('city', $event)"
            @touchend="onTouchEnd('city', $event)">
            <li v-for="(item, index) in cities" :key="index" :class="{ active: index === cityIndex }">{{ item.name }}
            </li>
          </ul>
        </div>
        <div class="picker-col" ref="districtCol">
          <ul @touchstart="onTouchStart('district', $event)" @touchmove="onTouchMove('district', $event)"
            @touchend="onTouchEnd('district', $event)">
            <li v-for="(item, index) in formatDistricts" :key="index" :class="{ active: index === districtIndex }">{{
              item }}</li>
          </ul>
        </div>
      </div>

      <!-- 选中指示器 -->
      <div class="picker-indicator"></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 显示控制
      isPickerVisible: false,

      // 选中值
      selectedProvince: '',
      selectedCity: '',
      selectedDistrict: '',

      // 临时选中值
      tempProvince: '',
      tempCity: '',
      tempDistrict: '',

      // 索引控制
      provinceIndex: 0,
      cityIndex: 0,
      districtIndex: 0,

      // 滚动状态
      touchState: {
        province: {
          startY: 0,
          currentY: 0,
          lastY: 0,
          isMoving: false,
          itemHeight: 44,
          startTime: 0,
          velocity: 0 // 用于惯性滚动
        },
        city: {
          startY: 0,
          currentY: 0,
          lastY: 0,
          isMoving: false,
          itemHeight: 44,
          startTime: 0,
          velocity: 0
        },
        district: {
          startY: 0,
          currentY: 0,
          lastY: 0,
          isMoving: false,
          itemHeight: 44,
          startTime: 0,
          velocity: 0
        }
      },

      // 地区数据
      areaData: [
        {
          name: '北京市',
          cities: [
            {
              name: '北京市',
              districts: ['东城区', '西城区', '朝阳区', '丰台区', '石景山区', '海淀区', '顺义区']
            }
          ]
        },
        {
          name: '上海市',
          cities: [
            {
              name: '上海市',
              districts: ['黄浦区', '徐汇区', '长宁区', '静安区', '普陀区', '虹口区', '杨浦区']
            }
          ]
        },
        {
          name: '广东省',
          cities: [
            {
              name: '广州市',
              districts: ['越秀区', '海珠区', '荔湾区', '天河区', '白云区', '黄埔区', '番禺区']
            },
            {
              name: '深圳市',
              districts: ['福田区', '罗湖区', '南山区', '宝安区', '龙岗区', '盐田区']
            },
            {
              name: '佛山市',
              districts: ['禅城区', '南海区', '顺德区', '三水区', '高明区']
            }
          ]
        }
      ]
    };
  },

  computed: {
    provinces() {
      return this.areaData;
    },

    cities() {
      if (this.provinces.length && this.provinceIndex >= 0) {
        return this.provinces[this.provinceIndex].cities || [];
      }
      return [];
    },

    districts() {
      if (this.cities.length && this.cityIndex >= 0) {
        return this.cities[this.cityIndex].districts || [];
      }
      return [];
    },

    formatDistricts() {
      return this.districts.map(district => {
        if (typeof district === 'string') {
          return district;
        }
        return district.name || '';
      });
    }
  },

  watch: {
    provinceIndex(newVal) {
      this.cityIndex = 0;
      this.districtIndex = 0;
      this.$nextTick(() => {
        this.updateScrollPosition('city');
        this.updateScrollPosition('district');
      });
    },

    cityIndex(newVal) {
      this.districtIndex = 0;
      this.$nextTick(() => {
        this.updateScrollPosition('district');
      });
    }
  },

  mounted() {
    this.$nextTick(() => {
      ['province', 'city', 'district'].forEach(type => {
        const element = this.$refs[`${type}Col`]?.querySelector('li');
        if (element) {
          this.touchState[type].itemHeight = element.offsetHeight;
        }
        this.updateScrollPosition(type);
      });
    });
  },

  methods: {
    showPicker() {
      this.isPickerVisible = true;
      this.tempProvince = this.selectedProvince;
      this.tempCity = this.selectedCity;
      this.tempDistrict = this.selectedDistrict;
      this.$nextTick(() => {
        this.updateScrollPositions();
      });
    },

    hidePicker() {
      this.isPickerVisible = false;
      this.selectedProvince = this.tempProvince;
      this.selectedCity = this.tempCity;
      this.selectedDistrict = this.tempDistrict;
    },

    confirmSelection() {
      this.selectedProvince = this.provinces[this.provinceIndex]?.name || '';
      this.selectedCity = this.cities[this.cityIndex]?.name || '';
      this.selectedDistrict = this.formatDistricts[this.districtIndex] || '';
      this.isPickerVisible = false;

      this.$emit('select', {
        province: this.selectedProvince,
        city: this.selectedCity,
        district: this.selectedDistrict
      });
    },

    onTouchStart(type, e) {
      e.preventDefault();
      const touch = e.touches[0];
      const state = this.touchState[type];

      state.startY = touch.clientY;
      state.lastY = touch.clientY;
      state.currentY = this.getTransformY(type);
      state.isMoving = true;
      state.startTime = Date.now();
      state.velocity = 0;
    },

    onTouchMove(type, e) {
      e.preventDefault();
      if (!this.touchState[type].isMoving) return;

      const touch = e.touches[0];
      const state = this.touchState[type];
      const currentY = touch.clientY;

      // 计算移动距离
      const diffY = currentY - state.lastY;
      state.lastY = currentY;

      // 计算新位置
      let newY = state.currentY + diffY;

      // 计算速度（用于惯性滚动）
      const now = Date.now();
      const timeDiff = now - state.startTime;
      if (timeDiff > 0) {
        state.velocity = diffY / timeDiff;
      }
      state.startTime = now;

      // 应用边界限制（带弹性效果）
      const maxScroll = 50; // 顶部弹性区域
      const minScroll = -((this[`${type}s`] || []).length - 1) * state.itemHeight - 50; // 底部弹性区域

      // 弹性效果
      if (newY > maxScroll) {
        newY = maxScroll + (newY - maxScroll) * 0.2;
      } else if (newY < minScroll) {
        newY = minScroll + (newY - minScroll) * 0.2;
      }

      // 更新位置
      state.currentY = newY;
      this.setTransformY(type, newY);
    },

    onTouchEnd(type, e) {
      if (!this.touchState[type].isMoving) return;

      const state = this.touchState[type];
      state.isMoving = false;

      // 获取当前位置和项目高度
      let currentY = state.currentY;
      const itemHeight = state.itemHeight;
      const itemsCount = (this[`${type}s`] || []).length;

      // 应用惯性滚动
      const inertiaDistance = state.velocity * 100; // 惯性距离
      currentY += inertiaDistance;

      // 计算最终位置（限制在有效范围内）
      const maxY = 0;
      const minY = -(itemsCount - 1) * itemHeight;

      // 边界处理
      if (currentY > maxY) {
        currentY = maxY;
      } else if (currentY < minY) {
        currentY = minY;
      }

      // 计算最终索引
      let index = Math.round(-currentY / itemHeight);
      index = Math.max(0, Math.min(index, itemsCount - 1));

      // 动画到目标位置
      this.animateToPosition(type, index, currentY);
    },

    // 动画过渡到目标位置
    animateToPosition(type, index, currentY) {
      const state = this.touchState[type];
      const targetY = -index * state.itemHeight;
      const distance = targetY - currentY;
      const duration = 200; // 动画持续时间
      const startTime = Date.now();

      const animate = () => {
        const now = Date.now();
        const progress = Math.min((now - startTime) / duration, 1);
        // 缓动函数 - 先快后慢
        const easeProgress = 1 - Math.pow(1 - progress, 3);
        const newY = currentY + distance * easeProgress;

        this.setTransformY(type, newY);

        if (progress < 1) {
          requestAnimationFrame(animate);
        } else {
          // 动画结束，更新最终状态
          state.currentY = targetY;
          this[`${type}Index`] = index;
        }
      };

      requestAnimationFrame(animate);
    },

    // 获取当前元素的Y轴偏移
    getTransformY(type) {
      const element = this.$refs[`${type}Col`]?.querySelector('ul');
      if (!element) return 0;

      const transform = window.getComputedStyle(element).transform;
      if (transform === 'none') return 0;

      const matrix = new DOMMatrix(transform);
      return matrix.m42; // 获取Y轴偏移
    },

    // 设置元素的Y轴偏移
    setTransformY(type, y) {
      const element = this.$refs[`${type}Col`]?.querySelector('ul');
      if (element) {
        element.style.transform = `translateY(${y}px)`;
      }
    },

    updateScrollPosition(type) {
      const index = this[`${type}Index`];
      const itemHeight = this.touchState[type].itemHeight;
      const targetY = -index * itemHeight;

      this.touchState[type].currentY = targetY;
      this.setTransformY(type, targetY);
    },

    updateScrollPositions() {
      ['province', 'city', 'district'].forEach(type => {
        const element = this.$refs[`${type}Col`]?.querySelector('li');
        if (element) {
          this.touchState[type].itemHeight = element.offsetHeight;
        }
        this.updateScrollPosition(type);
      });
    }
  }
};
</script>

<style scoped>
/* 触发按钮样式 */
.selected-area {
  width: 100%;
  padding: 12px 15px;
  background-color: #fff;
  border: 1px solid #eee;
  border-radius: 8px;
  font-size: 16px;
  color: #333;
  text-align: left;
}

.placeholder {
  color: #999;
}

/* 遮罩层 */
.picker-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 1000;
}

/* 选择器面板 */
.picker-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #fff;
  border-radius: 16px 16px 0 0;
  z-index: 1001;
}

/* 头部样式 */
.picker-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px;
  border-bottom: 1px solid #eee;
}

.picker-btn {
  padding: 8px 15px;
  background: none;
  border: none;
  font-size: 16px;
  cursor: pointer;
}

.cancel {
  color: #999;
}

.confirm {
  color: #1677ff;
}

.picker-title {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
  color: #333;
}

/* 内容区域 */
.picker-content {
  display: flex;
  height: 260px;
  overflow: hidden;
  position: relative;
}

.picker-col {
  flex: 1;
  height: 100%;
  overflow: hidden;
  position: relative;
}

.picker-col ul {
  list-style: none;
  padding: 0;
  margin: 0;
  transition: transform 0.03s ease-out;
  text-align: center;
  padding-top: 110px;
  /* 中间选中区域的位置 */
  padding-bottom: 110px;
}

.picker-col li {
  height: 44px;
  line-height: 44px;
  font-size: 16px;
  color: #999;
}

.picker-col li.active {
  color: #333;
  font-weight: 500;
}

/* 选中指示器 */
.picker-indicator {
  position: absolute;
  top: 110px;
  /* 修正指示器位置，与内容区域padding-top匹配 */
  left: 0;
  right: 0;
  height: 44px;
  pointer-events: none;
  box-sizing: border-box;
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
  background-color: rgba(255, 255, 255, 0.8);
}
</style>
